﻿#include "signup.h"
#include "ui_signup.h"
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonParseError>
#include <QMessageBox>
#include <QPainter>
#include <QFileDialog>
#include <QBuffer>

SignUp::SignUp(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::SignUp)
{
    ui->setupUi(this);

    SetPhoto(QPixmap(":/img/qq.png"));
}

SignUp::~SignUp()
{
    delete ui;
}

void SignUp::WriteToServer(const QJsonObject &obj)
{
    // 将QJsonObject包装成一个QJsonDocument对象,并将QJsonDocument转换为JSON格式的QByteArray
    auto data = QJsonDocument(obj).toJson();
    int size =  data.size(); // 获取数据(data)的长度
    socket->write((char*)&size,sizeof(int)); // 将数据长度写入套接字(告诉接收方数据多长)
    socket->write(data); // 将Json数据写入套接字
}

// 处理json逻辑
void SignUp::process(const QByteArray &data)
{
    auto obj = QJsonDocument::fromJson(data).object(); // 解析Json数据，允许访问Json数据中的各个字段
    qDebug() << "signup.cpp处理json逻辑:" << QJsonDocument(obj).toJson() << endl;

    if(obj["result"].toInt() == 0) // 如果Json数据中包含"result"字段且其值为0，则认为发生了错误
    {
        QMessageBox::information(this,"error",obj["msg"].toString()); // 弹出一个信息框显示具体的错误消息("msg"字段)
        return;
    }

    if(obj["request"] == "SIGNUP") // 请求类型为"SIGNUP"时，表示需要注册
    {
        if(obj["msg"] == "success")
        {
            QMessageBox::information(this,"提示", "注册成功!"); // 弹出一个信息框显示具体的错误消息("msg"字段)
            ui->lineEdit_account->clear();
            ui->lineEdit_passwd->clear();
            ui->lineEdit_name->clear();
            SetPhoto(QPixmap(":/img/qq.png"));
            emit GoBack();
            return;
        }
        else if(obj["msg"] == "repeat of name")
        {
            QMessageBox::information(this,"提示", "账号重复，注册失败!"); // 弹出一个信息框显示具体的错误消息("msg"字段)
            return;
        }
        else if(obj["msg"] == "fail")
        {
            QMessageBox::information(this,"提示", "注册失败，请稍后再试!"); // 弹出一个信息框显示具体的错误消息("msg"字段)
            return;
        }
    }
}

void SignUp::SetPhoto(const QPixmap &photo)
{
    QPixmap circlePhoto(ui->label_photo->size());
    circlePhoto.fill(Qt::transparent); // 父窗口颜色
    QPainter painter(&circlePhoto); // 在图上作画
    painter.setBrush(photo.scaled(ui->label_photo->size())); // 将原图作为要作画的背景画到新的pixmap
    painter.setPen(Qt::NoPen); // 无边缘线
    painter.setRenderHint(QPainter::Antialiasing); // 设置线条光滑
    painter.drawEllipse(0, 0, ui->label_photo->width(), ui->label_photo->height());
    ui->label_photo->setPixmap(circlePhoto);
}

void SignUp::mousePressEvent(QMouseEvent *e)
{
    if (e->button() == Qt::LeftButton)
    {
        auto facePos = ui->widget_5->mapFromParent(e->pos());
        auto pos = ui->label_photo->mapFromParent(facePos); // 父窗口的坐标转换成相对于子控件的坐标
        if (ui->label_photo->rect().contains(pos)) // photo矩形内
        {
            QString filepath = QFileDialog::getOpenFileName(this, "获取一张图片", "C:\\Users\\Default\\Desktop");
            if (filepath.size() == 0)
            {
                return;
            }
            SetPhoto(QPixmap(filepath));
        }
    }
}

void SignUp::GetSocket(QTcpSocket *socket)
{
    this->socket = socket; // 接收传递过来的套接字
}

void SignUp::on_pushButton_sure_clicked()
{
    qDebug() << "点击确定按钮" << endl;
    auto account = ui->lineEdit_account->text(); // 获取用户输入的账号
    auto passwd = ui->lineEdit_passwd->text(); // 获取用户输入的密码
    auto name = ui->lineEdit_name->text(); // 获取用户输入的用户名
    if (account == "" || passwd == "" || name == "")
    {
        QMessageBox::information(this,"提示", "请输入完整信息!");
        return;
    }

    QPixmap photo = *(ui->label_photo->pixmap()); // 获取用户图像数据

    // QPixmap -> 二进制数据 QByteArray
    QByteArray imageInfo;
    QBuffer buffer(&imageInfo); // 缓冲区
    buffer.open(QIODevice::WriteOnly);
    photo.toImage().save(&buffer, "PNG"); // 以png的形式将图像数据写入缓冲区

    QJsonObject obj; // 构建Json对象
    obj["request"] = "SIGNUP"; // 请求类型为SIGNUP
    obj["account"] = account; // 用户的账号
    obj["passwd"] = passwd; // 用户的密码
    obj["name"] = name; // 用户的名称
    obj["photo"] = QString::fromUtf8(imageInfo.toBase64()); // 用户的图像
    WriteToServer(obj); // 发送到服务器
}

void SignUp::on_pushButton_cancle_clicked()
{
    ui->lineEdit_account->clear();
    ui->lineEdit_passwd->clear();
    ui->lineEdit_name->clear();
    emit GoBack();
}
